package Olivia.olivia3d.vo
{
	import Olivia.olivia3d.model.AnimationMat;
	import Olivia.olivia3d.model.ms3d.MsGroup;
	import Olivia.olivia3d.model.ms3d.MsJointEx;
	import Olivia.olivia3d.model.ms3d.MsMaterial;
	import Olivia.olivia3d.model.ms3d.MsTriangle;
	import Olivia.olivia3d.shader.FragmentShader;
	import Olivia.olivia3d.shader.VertexShader;
	
	import com.adobe.utils.AGALMiniAssembler;
	
	import flash.display3D.Context3D;
	import flash.display3D.Context3DProgramType;
	import flash.display3D.Program3D;
	import flash.geom.Vector3D;

	public class Ms3dVo
	{
		public var msid:int = 0;
		public var name:String='';
		/**
		 * 0 base,1 animaition
		 */		
		public static const BaseType:int = 0;
		public static const AnimType:int = 1;
		public var type:int = BaseType;
		/**
		 * 
		 */		
		public var position:Vector3D = new Vector3D();
		public var vertexData:Vector.<Number>;
		public var dataPerVertex:int = 5;
		public var normalData:Vector.<Number>;
		public var triangleData:Vector.<MsTriangle>;
		/**
		 * 
		 */
		public var initGroupIdx:Boolean = false;
		public var groupData:Vector.<MsGroup>;
		public var materialData:Vector.<MsMaterial>;
		public var fAnimationFPS:Number;
		public var fCurrentTime:Number;
		public var iTotalFrames:int;		
		public var jointData:Vector.<MsJointEx>;
		public var _nowfps:int = 0;
		public var fps:Array = [1,53,55,88,90,114,117,181,184,236,
			237,304,305,360,361,423,424,493,494,556,
			557,601];
		//...
		public var shadowPro3D:Program3D;
		public var pro3D:Program3D;
		
		public function Ms3dVo()
		{
		}
		
		public function get nowfps():int
		{
			var temp:int = _nowfps;
			_nowfps++;
			if(_nowfps > iTotalFrames-1){
				_nowfps = 0;
			}
			return temp;
		}
		
		public function getJointDataForNextFrame():Vector.<Number>
		{
			var reArr:Array = [];
			var frame:int = nowfps;
			for each(var msjex:MsJointEx in jointData){
//				var tm:AnimationMat = new AnimationMat(
//					msjex.abAMat.orm.Mat.concat(
//						[msjex.abAMat.tx,msjex.abAMat.ty,msjex.abAMat.tz]));
////				trace(tm.toString());
//				tm.append(msjex.KFAmats[frame]);
////				trace(tm.toString());
				var tm:AnimationMat = msjex.KFAmats[frame];
				reArr = reArr.concat(tm.matrix_vec);
			}
			return Vector.<Number>(reArr);
		}
		
		public function getJointDataThisFrame():Vector.<Number>
		{
			var reArr:Array = [];
			var frame:int = _nowfps;
			for each(var msjex:MsJointEx in jointData){
				var tm:AnimationMat = msjex.KFAmats[frame];
				reArr = reArr.concat(tm.matrix_vec);
			}
			return Vector.<Number>(reArr);
		}
		
		public function getBoneVector(idx:int):Vector.<Number>
		{
			var reArr:Array = [];
			for(var i:int=0; i < vertexData.length; i+=dataPerVertex){
				reArr.push(vertexData[i+3]*3+idx);
//				trace(vertexData[i+3]); 
				reArr.push(idx);
				reArr.push(idx);
				reArr.push(idx);
			}
			return Vector.<Number>(reArr);
		}
		
		public function initProgram3D(context3D:Context3D):void
		{
			//program
			shadowPro3D = context3D.createProgram();
			pro3D = context3D.createProgram();
			//agal
			var vsAgal:AGALMiniAssembler = new AGALMiniAssembler();
			var fsAgal:AGALMiniAssembler = new AGALMiniAssembler();
			if(type == BaseType){
				//shadow
				vsAgal.assemble(Context3DProgramType.VERTEX,VertexShader.depthVsAgal(),false);
				fsAgal.assemble(Context3DProgramType.FRAGMENT,FragmentShader.depthFsAgal(),false);
				shadowPro3D.upload(vsAgal.agalcode,fsAgal.agalcode);
				//render
				vsAgal.assemble(Context3DProgramType.VERTEX,VertexShader.withShadowVsAgal(),false);
				fsAgal.assemble(Context3DProgramType.FRAGMENT,FragmentShader.getFsAgal(),false);
				pro3D.upload(vsAgal.agalcode,fsAgal.agalcode);
			}else if(type == AnimType){
				//shadow
				vsAgal.assemble(Context3DProgramType.VERTEX,VertexShader.depthVsAgalAni(),false);
				fsAgal.assemble(Context3DProgramType.FRAGMENT,FragmentShader.depthFsAgal(),false);
				shadowPro3D.upload(vsAgal.agalcode,fsAgal.agalcode);
				//render
				vsAgal.assemble(Context3DProgramType.VERTEX,VertexShader.withShadowVsAgalAni(),false);
				fsAgal.assemble(Context3DProgramType.FRAGMENT,FragmentShader.getFsAgal(),false);
				pro3D.upload(vsAgal.agalcode,fsAgal.agalcode);
			}
		}
	}
}